package com.server.runtime;

import java.rmi.RemoteException;
import java.util.ArrayList;

import com.server.order.orderMovementImpl;
import com.server.order.orderAttackImpl;
import com.server.systems.sensorSystemImpl;
import com.server.systems.weaponSystemImpl;

import combat.protocol.types.SensorSystemType;
import combat.protocol.types.WeaponSystemType;
import combat.protocol.data.DoublePoint;
import combat.protocol.data.PhysicalObject;
import combat.protocol.data.RemoteList;
import combat.protocol.interfaces.OrderInt;
import combat.protocol.interfaces.OnboardSystemInt;
import combat.protocol.interfaces.OnboardWeaponSystemInt;
import combat.protocol.interfaces.VehicleInt;
import combat.protocol.types.PhysicalObjectType;
import combat.protocol.types.VehicleType;

public class vehicleImpl extends PhysicalObject implements VehicleInt {
	private static final long serialVersionUID = 1L;
	
	private String name = "";
	private DoublePoint position = new DoublePoint(0,0);
	private int altitude = 0;
	private double direction = 0.0;
	private double speed = 0.0;
	private double fuel = 0.0;
	private int health = 0;
	private Boolean isLocked = false;
	private VehicleType vehicleType = VehicleType.UNKNOWN;
	private PhysicalObjectType POType = PhysicalObjectType.UNKNOWN;
	private ArrayList<OrderInt> orderList = new ArrayList<OrderInt>();
	private ArrayList<OnboardSystemInt> onBoardSystem = new ArrayList<OnboardSystemInt>();
	
	public vehicleImpl(String name, DoublePoint position, int altitude,
            double direction, double speed, double fuel, 
            int health, Boolean locked, VehicleType vehicleType, 
            PhysicalObjectType POType, ArrayList<OrderInt> orderList, ArrayList<OnboardSystemInt> onBoardSystem) {
		 
		super(POType, name, position, altitude, direction, speed);
		
		this.name = name;
		this.position = position;
		this.altitude = altitude;
		this.direction = direction;
		this.speed = speed;
		this.fuel = fuel;
		this.health = health;
		this.isLocked = locked;
		this.POType = POType;
		this.orderList = orderList;
		this.onBoardSystem = onBoardSystem;
		this.vehicleType = vehicleType;
		
		//Add weapon systems
		switch (this.vehicleType) {
			case UNKNOWN:
				break;
			case CONVOY:
				onBoardSystem.add(new sensorSystemImpl(200, SensorSystemType.RADAR));
				onBoardSystem.add(new sensorSystemImpl(100, SensorSystemType.SIGHT));
				break;
			case FRIGATE:
				onBoardSystem.add(new weaponSystemImpl(20, WeaponSystemType.GOALKEEPER));
				onBoardSystem.add(new weaponSystemImpl(15, WeaponSystemType.GUIDED_MISSILELAUNCHER));
				onBoardSystem.add(new weaponSystemImpl(10, WeaponSystemType.TORPEDOLAUNCHER));
				onBoardSystem.add(new weaponSystemImpl(50, WeaponSystemType.UNGUIDED_MISSILELAUNCHER));
				onBoardSystem.add(new sensorSystemImpl(100, SensorSystemType.RADAR));
				break;
			case SUBMARINE:
				onBoardSystem.add(new weaponSystemImpl(5, WeaponSystemType.TORPEDOLAUNCHER));
				onBoardSystem.add(new sensorSystemImpl(50, SensorSystemType.SONAR));
				break;
			default:
				break;
		}
	}
	
	public PhysicalObjectType getType() {
		return this.POType;
	}
	
	public void setType(PhysicalObjectType phyObjType) {
		this.POType = phyObjType;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public DoublePoint getPosition() {
		return this.position;
	}
	
	public void setPosition(DoublePoint position) {
		this.position = position;
	}

	public int getAltitude() {
		return this.altitude;
	}

	public void setAltitude(int altitude) {
		this.altitude = altitude;
	}

	public double getDirection() {
		return this.direction;
	}

	public void setDirection(double direction) {
		this.direction = direction;
	}

	public double getSpeed() {
		return this.speed;
	}

	public void setSpeed(double speed) {
		this.speed = speed;
	}

	public double getFuel() {
		return this.fuel;
	}

	public void setFuel(double fuel) {
		this.fuel = fuel;
	}

	public int getHealth() {
		return this.health;
	}

	public void setHealth(int health) {
		this.health = health;
	}

	public Boolean getLocked() {
		return this.isLocked;
	}

	public void setLocked(Boolean locked) {
		this.isLocked = locked;
	}

	public void lock() {
		this.isLocked = true;
	}

	public void unlock() {
		this.isLocked = false;
	}

	public ArrayList<OnboardSystemInt> getOnboardSystems() {
		return this.onBoardSystem;
	}

	public void setOnboardSystems(ArrayList<OnboardSystemInt> onboardSystems) {
		this.onBoardSystem = onboardSystems;
	}

	public ArrayList<OrderInt> getOrders() {
		return this.orderList;
	}

	public void setOrders(ArrayList<OrderInt> orders) {
		this.orderList = orders;
	}

	public VehicleType getVehicleType() {
		return this.vehicleType;
	}

	public void setVehicleType(VehicleType vehicleType) {
		this.vehicleType = vehicleType;
	}

	public void orderMove(int orderID, Object target, int speed) {
		this.orderList.add(new orderMovementImpl(target, speed));
	}

	public void orderAttack(int orderID, Object target, OnboardWeaponSystemInt system) {
		System.out.println("Ammo: "+system.getAmmo());
		if (system.getAmmo() > 0) {
			this.orderList.add(new orderAttackImpl(target, system));
			system.fire(target);
		}
	}

	public void orderCancel(OrderInt order) {
		this.orderList.remove(order); 
	}

	@Override
	public RemoteList getOnboardSystems_Remote() {
		try {
			return new RemoteList(getOnboardSystems());
		} catch(RemoteException e){
			System.out.println("ERROR: Update getOnboardSystems function failed");
		}
		
		return new RemoteList();
	}

	@Override
	public RemoteList getOrders_Remote() {
		try {
			return new RemoteList(getOrders());
		} catch (RemoteException e) {
			System.out.println("ERROR: Update getOrders function failed");
		}
		return new RemoteList();
	}
}
